/*
 * stable_matcher.h
 *
 *  Created on: May 25, 2011
 *      Author: tqlong
 */

#ifndef STABLE_MATCHER_H_
#define STABLE_MATCHER_H_
#include "matcher.h"

template <typename D1, typename D2>
struct StableMatcher : public Matcher<D1, D2>
{
  typedef Matcher<D1, D2>   __Base;
  typedef typename __Base::dataset1_type dataset1_type;
  typedef typename __Base::dataset2_type dataset2_type;
  typedef typename __Base::vec_type vec_type;
  typedef KDTree<D1>        tree1_type;
  typedef KDTree<D2>        tree2_type;
  typedef RangeVisitor<tree1_type> visitor1_type;
  typedef struct
  {
    int idx;
    double dist;
  } entry_type;

  typedef struct
  {
    bool operator()(const entry_type& e1, const entry_type& e2) const { return e1.dist < e2.dist; }
  } less_entry;
  typedef std::vector<int>  vint_type;
  typedef std::vector<double>  vdouble_type;
  typedef std::vector<entry_type>  ventry_type;

  tree1_type *m_tree;
  double m_r;
  double m_norm;

  vint_type m_matchIdx;
  vdouble_type m_matchDist;
  vint_type m_currentPos;

  std::vector<ventry_type> m_range;

  StableMatcher(dataset1_type& data1, dataset2_type& data2, double r, double norm);

  void doMatch();

  int match1(int i) const { return m_matchIdx[i+this->m_data2.n()]; }
  int match2(int i) const { return m_matchIdx[i] == -1 ? -1 : m_matchIdx[i]-this->m_data2.n(); }
protected:
  void computeRange();
  void match(int m, int w, double dist);
};

#include "stable_matcher_impl.h"

#endif /* STABLE_MATCHER_H_ */
